package com.x.provider.general.service.cms;


import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.x.core.utils.BeanUtil;
import com.x.core.utils.MyBatisPlusUtil;
import com.x.core.web.page.PageHelper;
import com.x.core.web.page.PageList;
import com.x.kafka.MqTemplate;
import com.x.provider.api.general.constants.GeneralEventTopic;
import com.x.provider.api.general.enums.ItemToggleRelationEnum;
import com.x.provider.api.general.model.dto.cms.ItemToggleRelationDTO;
import com.x.provider.api.general.model.dto.cms.ItemToggleRelationListReqDTO;
import com.x.provider.api.general.model.dto.cms.ItemToggleRelationSaveReqDTO;
import com.x.provider.api.general.model.event.ItemToggleRelationEvent;
import com.x.provider.general.mapper.ItemToggleRelationMapper;
import com.x.provider.general.model.domain.cms.ContentMediaVideo;
import com.x.provider.general.model.domain.cms.ItemToggleRelation;
import com.x.provider.general.model.query.cms.ContentMediaVideoQuery;
import com.x.provider.general.model.query.cms.ItemToggleRelationQuery;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;

@Service
public class ItemToggleRelationServiceImpl implements ItemToggleRelationService{

    private final ItemToggleRelationMapper itemToggleRelationMapper;
    private final MqTemplate mqTemplate;

    public ItemToggleRelationServiceImpl(ItemToggleRelationMapper itemToggleRelationMapper,
                                         MqTemplate mqTemplate){
        this.itemToggleRelationMapper = itemToggleRelationMapper;
        this.mqTemplate = mqTemplate;
    }

    @Override
    public ItemToggleRelation toggleRelation(ItemToggleRelationSaveReqDTO req) {
        ItemToggleRelationQuery query = ItemToggleRelationQuery.builder().fromItemType(req.getFromItemType()).fromItemId(req.getFromItemId()).toItemType(req.getToItemType()).toItemId(req.getToItemId()).relationType(req.getRelationType()).build();
        ItemToggleRelation fromRelation = get(query);
        Boolean firstRelation = fromRelation == null ? true : false;
        if (fromRelation != null && fromRelation.getRelation().equals(req.getRelation())){
            return fromRelation;
        }
        if (fromRelation == null){
            fromRelation = ItemToggleRelation.builder().fromItemId(req.getFromItemId()).toItemId(req.getToItemId()).toItemType(req.getToItemType()).relationType(req.getRelationType()).build();
        }
        fromRelation.setRelation(req.getRelation());
        ItemToggleRelation toRelation = get(ItemToggleRelationQuery.builder().fromItemId(req.getToItemId()).fromItemType(req.getToItemType()).toItemId(req.getFromItemId())
                .toItemType(req.getFromItemType())
                .relationType(req.getRelationType()).build());
        Integer bothRelation = getBothRelation(fromRelation, toRelation);
        fromRelation.setBothRelation(bothRelation);
        fromRelation.setToggleTimeUtc(new Date());
        MyBatisPlusUtil.save(itemToggleRelationMapper, fromRelation);
        if (toRelation != null){
            toRelation.setBothRelation(fromRelation.getBothRelation());
            MyBatisPlusUtil.save(itemToggleRelationMapper, toRelation);
        }
        ItemToggleRelationEvent event = BeanUtil.prepare(fromRelation, ItemToggleRelationEvent.class);
        mqTemplate.send(GeneralEventTopic.TOPIC_NAME_ITEM_TOGGLE_RELATION, StrUtil.format("{}-{}", event.getFromItemType(), event.getFromItemId()), event);
        return fromRelation;
    }

    private Integer getBothRelation(ItemToggleRelation fromRelation, ItemToggleRelation toRelation){
        if (toRelation == null || toRelation.getRelation().equals(ItemToggleRelationEnum.NO_RELATION.getValue()) || !fromRelation.getRelation().equals(toRelation.getRelation())){
            return ItemToggleRelationEnum.NO_RELATION.getValue();
        }
        return fromRelation.getRelation();
    }

    public ItemToggleRelation get(ItemToggleRelationQuery query){
        return itemToggleRelationMapper.selectOne(build(query));
    }

    @Override
    public PageList<ItemToggleRelation> list(ItemToggleRelationListReqDTO req){
        ItemToggleRelationQuery query = BeanUtil.prepare(req, ItemToggleRelationQuery.class);
        query.setPageLimit(PageHelper.toPageLimit(req.getPageDomain()));
        List<ItemToggleRelation> itemToggleRelations = itemToggleRelationMapper.selectList(build(query).orderByDesc(ItemToggleRelation::getId));
        if (itemToggleRelations.isEmpty()){
            return PageList.empty();
        }
        return new PageList<>(itemToggleRelations, req.getPageDomain(), CollectionUtils.lastElement(itemToggleRelations).getId());
    }

    private LambdaQueryWrapper<ItemToggleRelation> build(ItemToggleRelationQuery query){
        LambdaQueryWrapper<ItemToggleRelation> queryWrapper = new LambdaQueryWrapper<>();
        if (query.getFromItemId() != null){
            queryWrapper.eq(ItemToggleRelation::getFromItemId, query.getFromItemId());
        }
        if (query.getToItemId() != null){
            queryWrapper.eq(ItemToggleRelation::getToItemId, query.getToItemId());
        }
        if (query.getRelation() != null){
            queryWrapper.eq(ItemToggleRelation::getRelation, query.getRelation());
        }
        if (query.getRelationType() != null){
            queryWrapper.eq(ItemToggleRelation::getRelationType, query.getRelationType());
        }
        if (!CollectionUtils.isEmpty(query.getFromItemIdList())){
            queryWrapper.in(ItemToggleRelation::getFromItemId, query.getFromItemIdList());
        }
        if (!CollectionUtils.isEmpty(query.getToItemIdList())){
            queryWrapper.in(ItemToggleRelation::getToItemId, query.getToItemIdList());
        }

        if (query.getRelationType() != null){
            queryWrapper.eq(ItemToggleRelation::getRelationType, query.getRelationType());
        }
        if (query.getRelation() != null){
            queryWrapper.eq(ItemToggleRelation::getRelation, query.getRelation());
        }
        if (query.getBothRelation() != null){
            queryWrapper.eq(ItemToggleRelation::getBothRelation, query.getBothRelation());
        }
        if (query.getPageLimit() != null){
            queryWrapper.last(PageHelper.toPageLimitSql(query.getPageLimit()));
        }
        if (query.getLtId() != null){
            queryWrapper.lt(ItemToggleRelation::getId, query.getLtId());
        }
        if (query.getFromItemType() != null){
            queryWrapper.eq(ItemToggleRelation::getFromItemType, query.getFromItemType());
        }
        if (query.getToItemType() != null){
            queryWrapper.eq(ItemToggleRelation::getToItemType, query.getToItemType());
        }
        if (query.getLeToggleTimeUtc() != null){
            queryWrapper.le(ItemToggleRelation::getToggleTimeUtc, query.getLeToggleTimeUtc());
        }
        return queryWrapper;
    }
}
